package com.las.nogu.controller.home;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.HttpKit;
import com.jfinal.kit.StrKit;
import com.las.bot.dao.SovitsDao;
import com.las.nogu.commond.Constant;
import com.las.nogu.controller.BaseController;
import com.model.SovitsSetting;
import com.utils.RedisUtils;
import com.utils.ThreadUtil;
import com.utils.osu.OsuApi2;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.util.ConcurrentReferenceHashMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;

@RestController
@RequestMapping("/home")
public class HomeController extends BaseController {

    private final Log logger = LogFactory.getLog(HomeController.class);

    private ThreadPoolExecutor executor = ThreadUtil.getPool();

    @Autowired
    private SovitsDao sovitsDao;

    @RequestMapping("/bck")
    public String bck(HttpSession session) {
        String result = OsuApi2.getInstanceByToken(getAuthToken(session)).getBackgrounds();
        JSONObject obj = JSONObject.parseObject(result);
        if (null != obj) {
            JSONArray bckList = obj.getJSONArray("backgrounds");
            Random random = new Random();
            int index = random.nextInt(bckList.size());
            JSONObject oneBck = bckList.getJSONObject(index);
            return oneBck.getString("url");
        }
        return null;
    }

    @Scope(value = "prototype")
    @RequestMapping("/statistics")
    public Object statistics(HttpSession session) {
        if (RedisUtils.hasKey(Constant.OSU_USER_ALLMODE + getOsuUserId(session))) {
            String json = RedisUtils.get(Constant.OSU_USER_ALLMODE + getOsuUserId(session)).toString();
            return JSONObject.parseObject(json, Map.class);
        } else {
            List<String> modes = Arrays.asList("osu", "taiko", "mania", "fruits");
            ConcurrentReferenceHashMap<String, Object> map = new ConcurrentReferenceHashMap<>();
            modes.stream().parallel().forEach(m -> {
                String result = OsuApi2.getInstanceByToken(getAuthToken(session)).getMeInfo(m);
                JSONObject obj = JSONObject.parseObject(result);
                map.put(m, obj);
            });
            AtomicInteger ac = new AtomicInteger(0);
            if (map.containsKey("osu") && null != map.get("osu")) {
                ac.addAndGet(1);
            }
            if (map.containsKey("taiko") && null != map.get("taiko")) {
                ac.addAndGet(1);
            }
            if (map.containsKey("mania") && null != map.get("mania")) {
                ac.addAndGet(1);
            }
            if (map.containsKey("fruits") && null != map.get("fruits")) {
                ac.addAndGet(1);
            }
            if (ac.get() == 4) {
                RedisUtils.set(Constant.OSU_USER_ALLMODE + getOsuUserId(session), JSONObject.toJSONString(map), Constant.MIN_SESSION_TIME);
                return map;
            } else {
                return null;
            }
        }
    }

    @RequestMapping("/chat")
    public String chat(HttpServletRequest request) {
        String command = request.getParameter("command");
        logger.info("机器人聊天接受信息：" + command);
        Object obj = RedisUtils.get(Constant.GPT_SESSION);
        String sId = "";
        if (null != obj) {
            sId = obj.toString();
            logger.info("gpt会话ID：" + sId);
        }
        SovitsSetting setting = sovitsDao.findByName("gpt");
        SovitsSetting setting2 = sovitsDao.findByName("gptRule");
        if (ObjectUtil.isNotNull(setting)) {
            String key = setting.getCodeValue();
            if (StrUtil.isBlank(sId)) {
                sId = getGPTSession(key,setting2.getCodeValue());
            }
            String finalSId = sId;
            if (StrUtil.isNotBlank(finalSId)) {
                executor.execute(() -> {
                    Map<String, String> params = new HashMap<>();
                    params.put("msg", command);
                    params.put("pId", "");
                    params.put("uId", "");
                    params.put("key", key);
                    params.put("sId", finalSId);
                    String result = HttpKit.post("http://vits.natapp1.cc/dwchat/gpt", params, null);
                    if (StrKit.notBlank(result)) {
                        logger.info("gpt响应结果：" + result);

                    }

                });
            }
        }
        return "success";
    }

    private String getGPTSession(String key,String rule) {
        Object obj = RedisUtils.get(Constant.GPT_SESSION);
        if (null != obj) {
            return obj.toString();
        }
        String result = HttpKit.post("http://550w.fun/api/gptPlus/api/session/" + key, null);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject.getIntValue("code") == 200) {
            String sId = jsonObject.getString("data");
            Map<String, Object> params = new HashMap<>();
            params.put("apiKey", key);
            params.put("msg", rule);
            params.put("sessionId", sId);
            String result2 = HttpUtil.post("http://550w.fun/api/gptPlus/api/chat", params);
            JSONObject jsonObject2 = JSONObject.parseObject(result2);
            if (jsonObject2.getIntValue("code") == 200) {
                logger.info("创建GPT会话成功");
                logger.info(jsonObject2.toJSONString());
                RedisUtils.set(Constant.GPT_SESSION, sId);
            }
            return sId;

        }
        return null;

    }
}
